// $Id: OscilloscopeM.nc,v 1.2.2.4 2003/08/26 09:08:06 cssharp Exp $

/*									tab:4
 * "Copyright (c) 2000-2003 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Copyright (c) 2002-2003 Intel Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE     
 * file. If you do not find these files, copies can be found by writing to
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
 * 94704.  Attention:  Intel License Inquiry.
 */
/*
 * Authors:   Jason Hill
 * History:   created 10/5/2001
 * 
 */

/**
 * @author Jason Hill
 */

includes KrzytomMsg;

/**
 * This module implements the OscilloscopeM component, which
 * periodically takes sensor readings and sends a group of readings 
 * over the UART. BUFFER_SIZE defines the number of readings sent
 * in a single packet. The Yellow LED is toggled whenever a new
 * packet is sent, and the red LED is turned on when the sensor
 * reading is above some constant value.
 */
module KrzytomM
{
  provides interface StdControl;
  uses {
    interface Timer;
    interface Leds;
    interface StdControl as CommControl;
    interface SendMsg as DataMsg;
    interface ReceiveMsg as IncrementMsg;
  }
}
implementation
{
  TOS_Msg msg;
  bool pending;

  /**
   * Used to initialize this component.
   */
  command result_t StdControl.init() {
    call Leds.init();
    call Leds.yellowOff(); call Leds.redOff(); call Leds.greenOff();

    call CommControl.init();
    
    dbg(DBG_BOOT, "OSCOPE initialized\n");
    return SUCCESS;
  }

  /**
   * Starts the SensorControl and CommControl components.
   * @return Always returns SUCCESS.
   */
  command result_t StdControl.start() {
	if (TOS_LOCAL_ADDRESS == 0) {
    	call Timer.start(TIMER_REPEAT, 5000);
	}
	call CommControl.start();
    return SUCCESS;
  }

  /**
   * Stops the SensorControl and CommControl components.
   * @return Always returns SUCCESS.
   */
  command result_t StdControl.stop() {
	if (TOS_LOCAL_ADDRESS == 0) {
		call Timer.stop();
	}
	call CommControl.stop();
    return SUCCESS;
  }

  task void dataTask() {
    struct KrzytomMsg *pack;

	if (!pending){
		pending = TRUE;

		atomic {
		  pack = (struct KrzytomMsg *)msg.data;
		}

		pack->sourceMoteID = TOS_LOCAL_ADDRESS;
		
		/* Try to send the packet. Note that this will return
		 * failure immediately if the packet could not be queued for
		 * transmission.
		 */
		if (call DataMsg.send(TOS_BCAST_ADDR, sizeof(struct KrzytomMsg), &msg)) {
			call Leds.yellowToggle();

			return;
		}
	}
  }
  
  /**
   * Signalled when the previous packet has been sent.
   * @return Always returns SUCCESS.
   */
  event result_t DataMsg.sendDone(TOS_MsgPtr sent, result_t success) {
	pending = FALSE;
    return SUCCESS;
  }

  /**
   * Signalled when the clock ticks.
   * @return The result of calling ADC.getData().
   */
  event result_t Timer.fired() {
	post dataTask();
    return SUCCESS;
  }

  /**
   * Signalled when the reset message counter AM is received.
   * @return The free TOS_MsgPtr. 
   */
  event TOS_MsgPtr IncrementMsg.receive(TOS_MsgPtr m) {

    struct KrzytomMsg *pack, *packr;
	int i;


	  if (TOS_LOCAL_ADDRESS == 0) {
		  return m;
	  }

    atomic {
      pack = (struct KrzytomMsg *)msg.data;
      packr = (struct KrzytomMsg *)m->data;
    }

	for (i = 0; i < BUFFER_SIZE; i++) {
		pack->data[i] = packr->data[i] + 1;
	}

	post dataTask();

	return m;
  }
}
